<template>
  <div class="g-progress-button" v-if="showProgressButton">
    <div class="g-progress-button--bg"></div>
    <div class="g-progress-button--progress" :style="buttonLoadingStyle"></div>
    <div class="g-progress-button--text g-flex-center-center"
      >{{ props.text }}{{ rateFormat(displayRate, 0) }}
    </div>
  </div>
</template>
<script lang="ts" setup name="CProgressButton">
import {
  ref,
  computed,
  defineProps,
  withDefaults,
  defineEmits,
  watch,
  defineExpose,
  onUnmounted
} from 'vue';
import { rateFormat } from '@/utils';
import {
  RefreshStatusNumberInfo,
  useAsyncStatusRefreshWidthProgress
} from '@/hooks/useAsyncStatusRefreshWidthProgress';

// 入参及格式
interface GProgressProps {
  // 刷新中的文本
  text: string;
  // 刷新状态的方法
  refreshStatusFn: () => Promise<RefreshStatusNumberInfo>;
}
const props = withDefaults(defineProps<GProgressProps>(), {});
const emit = defineEmits(['success']);
// 循环间隔，1000ms
const LOOP_GAP = 3000;
// 每秒帧率
const FRAME = 60;
// 每帧增长的百分比数值 = 循环间隔(s) * 每秒帧率
const PERCENT_GROW_FRAME = (LOOP_GAP / 1000) * FRAME;

const { isRefreshing, refreshStatusNumber, defaultNumber, handleStartRefresh } =
  useAsyncStatusRefreshWidthProgress(props.refreshStatusFn, handleRefreshSuccess, LOOP_GAP);

// 是否显示进度条按钮
const showProgressButton = ref(false);
// 进度条百分比
const buttonLoadingStyle = computed(() => {
  return {
    width: displayRate.value * 100 + '%'
  };
});
// 接口返回的百分比
const currentRate = computed(() => {
  if (!refreshStatusNumber.value.total) return 0;
  return refreshStatusNumber.value.current / refreshStatusNumber.value.total;
});
// 默认百分比
const defaultRate = computed(() => {
  if (!defaultNumber.value?.total) return 0;
  return defaultNumber.value.current / defaultNumber.value.total;
});
// 页面展示的百分比数值
// NOTE 通过代码控制在0 - 1之间
const displayRate = ref(0);
// 每次循环增长的数值
const rateGrow = ref(0);
let timer: any;
watch(
  [() => currentRate.value, () => isRefreshing.value, () => defaultRate.value],
  ([percent, refreshing, defaultRate]) => {
    console.log('progress-button watch percent start', percent, refreshing, defaultRate);
    if ((percent === 0 || (percent && percent <= 1)) && refreshing) {
      if (!showProgressButton.value) showProgressButton.value = true;
      // 默认值
      if (defaultRate && defaultRate > displayRate.value) {
        displayRate.value = defaultRate;
        return;
      }
      rateGrow.value = percent - displayRate.value;
      // 如果增长小于等于0，不往下执行，防止出现负增长
      if (rateGrow.value <= 0) {
        return;
      }
      // 如果已经有循环了，清除循环重新开始设置，一般这时候是已经清除了的
      if (timer) {
        clearInterval(timer);
      }
      // 循环定时器在页面展示百分比增长
      timer = setInterval(() => {
        // 跑完了当前一段，则停止
        if (displayRate.value >= percent) {
          clearInterval(timer);
          timer = null;
          return;
        }
        // 下一帧百分比
        const nextPercent = displayRate.value + rateGrow.value / PERCENT_GROW_FRAME;
        // 跑完了100%，则停止
        if (nextPercent >= 1) {
          displayRate.value = 1;
          clearInterval(timer);
          timer = null;
          return;
        } else {
          displayRate.value = nextPercent;
        }
      }, 1000 / FRAME);
    }
  }
);

// 接口获取到刷新成功后触发
function handleRefreshSuccess(params: any) {
  console.log('progress-button handleRefreshSuccess', params, displayRate.value);
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
  if (displayRate.value < 1) {
    // NOTE 当刷新结束时 展示的百分比不到1时，重新设置定时器将百分比在1秒内跑到1
    // 循环定时器在页面展示百分比增长
    rateGrow.value = 1 - displayRate.value;
    timer = setInterval(() => {
      // 下一帧百分比数值
      const nextPercent = displayRate.value + rateGrow.value / FRAME;
      // 跑完了100%，则停止
      if (nextPercent >= 1) {
        displayRate.value = 1;
        clearInterval(timer);
        timer = null;
        handleProgressComplete(params);
        return;
      } else {
        displayRate.value = nextPercent;
      }
    }, 1000 / FRAME);
  } else {
    handleProgressComplete(params);
  }
}

// 进度条跑完后操作
function handleProgressComplete(params?: any) {
  showProgressButton.value = false;
  emit('success', params);
  displayRate.value = 0;
  rateGrow.value = 0;
}

onUnmounted(() => {
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
});

// 触发刷新操作
function startRefresh(params?: any) {
  console.log('startRefresh', startRefresh);
  displayRate.value = 0;
  rateGrow.value = 0;
  if (timer) {
    clearInterval(timer);
    timer = null;
  }
  handleStartRefresh(params);
}

defineExpose({
  // 是否在刷新
  refreshStatus: isRefreshing.value,
  // 是否显示进度条按钮
  showProgressButton,
  startRefresh
});
</script>
<style lang="scss" scoped>
.g-progress-button {
  position: relative;
  width: 130px;
  height: 32px;
  // display: inline-flex;
  // justify-content: center;
  // align-items: center;
  // line-height: 1;
  // padding: 8px 15px;
  // height: 32px;
  // border: 1px solid #dcdfe6;
  // background: #fff;
  // user-select: none;
  // font-size: 14px;
  // color: #51596c;
  // text-align: center;
  // > span {
  //   display: inline-flex;
  //   align-items: center;
  // }
  .g-progress-button--bg {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    background: #03ac82;
    box-shadow: 0px 2px 2px 0px rgba(3, 172, 130, 0.1);
    border-radius: 2px;
  }
  .g-progress-button--progress {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    height: 32px;
    background: #018868;
    border-radius: 2px;
  }
  .g-progress-button--text {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 3;
    width: 100%;
    height: 100%;
    background: transparent;
    font-size: 14px;
    font-weight: 400;
    color: #ffffff;
    line-height: 10px;
  }
}
</style>
